﻿define(['config','utils','presenter'], function (config, utils,presenter) {
  var logger = config.logger;
  var EntitySet = (function() {
   
    return function(getFunction, mapper){
      this.getFunction = getFunction;
      this.mapper = mapper;
    }
  })();
  EntitySet.prototype = (function(){
        // returns the model item produced by merging dto into context
     var mapToContext = function(dtoList, items, results, sortFunction) {
      // Loop through the raw dto list and populate a dictionary of the items
      var self = this;
      var mapper = self.mapper;
      items = _.reduce(dtoList, function(memo, dto) {
        var id = mapper.getDtoId(dto);
        memo[id] = mapper.fromDto(dto);
        return memo;
      }, {});
      itemsToArray(items, results, sortFunction);
      return items;
      // must return these
    };
    var itemsToArray = function(items, observableArray, sortFunction) {
      // Maps the memo to an observableArray,
      // then returns the observableArray
      if (!observableArray)
        return;
      // Create an array from the memo object
      var underlyingArray = utils.mapMemoToArray(items);
      if (sortFunction) {
        underlyingArray = _.sortBy(underlyingArray, sortFunction);
      }
      observableArray(underlyingArray);
    };
    var getData = function(options, overwriteFunction) {
      var self = this;
      var items = {};
      var executeFunc = this.getFunction;
      return $.Deferred(function(def) {
        var results = options.results, sortFunction = options && options.sortFunction, callback = options && options.callback;
        param = options && options.param;
        viewModel = options && options.viewmodel;
        // If the internal items object doesnt exist,
        // or it exists but has no properties,
        // or we force a refresh
        if (this.overwriteFunction != undefined) {
          executeFunc = this.overwriteFunction;
        };
        executeFunc({
          success : function(dto) {
          	var dtoList = [];
          	if (!_.isArray(dto)){
	          	dtoList.push(dto);
          	} else {
          		dtoList = dto;
          	}
            self.mapToContext(dtoList, items, results, sortFunction);
            if (callback) {
              callback(results(), viewModel);
            }
            def.resolve(results);
          },
          error : function(response) {
              presenter.toggleActivity(false);
            	def.reject();
          }
        }, param);

      }).promise();
    };
    return {
      getData: getData,
      mapToContext: mapToContext,
      itemsToArray: itemsToArray
    }
  })();
  return EntitySet;
}); 